package com.sskj.postar.controller;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sskj.postar.core.ret.HttpResponse;
import com.sskj.postar.core.ret.HttpResult;
import com.sskj.postar.core.utils.ApplicationUtils;
import com.sskj.postar.core.utils.InviteCodeUtil;
import com.sskj.postar.core.utils.RedisUtil;
import com.sskj.postar.dto.RegisterDto;
import com.sskj.postar.model.*;
import com.sskj.postar.service.*;
import io.swagger.annotations.ApiResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * @Description: UserController类
 * @date 2018/11/06 13:46
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Resource
    private UserService userService;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private TokenService tokenService;
    @Resource
    private UserAuthInfoService userAuthInfoService;
    @Resource
    private UserPayInfoService userPayInfoService;
    @Resource
    private UserWalletAddressService userWalletAddressService;
    @Resource
    private SystemAssetService systemAssetService;
    @Resource
    private UserAssetService userAssetService;
    @Resource
    private UserAssetRecordService userAssetRecordService;
    @Value("${config.inviteCode.require}")
    boolean isInviteCodeRequire;

    /**
     * 注册账号
     *
     * @return
     * @throws Exception
     */
    @PostMapping("/register")
    public HttpResult<Integer> register(@Valid RegisterDto registerDto) throws Exception {
        String account = registerDto.getAccount();
        String pws = registerDto.getPws();
        String code = registerDto.getCode();
        String inviteCode = registerDto.getInviteCode();
        if (redisUtil.get(account) == null) {
            return HttpResponse.makeErrRsp("验证码已过期");
        }
        if (!redisUtil.get(account).equals(code)) {
            return HttpResponse.makeErrRsp("验证码错误");
        }
        User userOld = null;
        User user = new User();
        if (account.contains("@")) {
            List<User> users = userService.selectListBy("email", account);
            if (users.size() > 0) {
                userOld = users.get(0);
            }
            user.setEmail(account);
        } else {
            List<User> users = userService.selectListBy("mobile", account);
            if (users.size() > 0) {
                userOld = users.get(0);
            }
            user.setMobile(account);
        }
        if (userOld != null) {
            return HttpResponse.makeErrRsp("账户已存在");
        }

        User inviter = userService.selectBy("code", inviteCode);
        if (isInviteCodeRequire) {
            if (inviteCode == null) {
                return HttpResponse.makeErrRsp("请填写邀请码");
            }
            if (inviter == null) {
                return HttpResponse.makeErrRsp("该邀请码不存在");
            }
        }
        if (inviter != null) {
            user.setInviterId(inviter.getId());
        }

        user.setAccount(ApplicationUtils.getUUID());
        user.setLoginPwd(pws);
        user.setCreateTime(new Date());
        user.setCode(InviteCodeUtil.randomInviteCode());
        Integer state = userService.insert(user);
        redisUtil.del(account);
        return HttpResponse.makeOKRsp(state);
    }

    /**
     * 登录
     *
     * @param type    登录设备类型
     * @param account 账号 手机号或邮箱
     * @param pwd     登陆密码
     * @return
     */
    @ApiResponse(code = 0, response = User.class, message = "成功")
    @PostMapping("/login")
    public HttpResult<User> login(@RequestHeader String type, String account, String pwd, HttpServletResponse response) {
        User user = new User();
        user.setLoginPwd(pwd);
        if (account.contains("@")) {
            user.setEmail(account);
        } else {
            user.setMobile(account);
        }
        User userSelect = userService.selectOne(user);
        if (userSelect != null) {
            String tokenStr = ApplicationUtils.randomUUID();
            Token token = new Token();
            token.setToken(tokenStr);
            token.setType(type);
            token.setUserId(userSelect.getId());
            tokenService.delete(userSelect.getId(), type);
            tokenService.insert(token);
            Cookie cookie = new Cookie("token", tokenStr);
            cookie.setPath("/");
            response.addCookie(cookie);
            userSelect.setLoginPwd("");
            userSelect.setPayPwd("");
            return HttpResponse.makeOKRsp("登录成功", userSelect);
        } else {
            return HttpResponse.makeErrRsp("账号或密码错误");
        }
    }

    /**
     * 更新密码
     *
     * @param oldPwd 原密码
     * @param newPwd 新密码
     * @return
     */
    @PostMapping("/changeLoginPwd")
    public HttpResult changeLoginPwd(HttpServletRequest request, String oldPwd, String newPwd) {
        Integer id = (Integer) request.getAttribute("id");
        User user = userService.selectById(id + "");
        if (user == null) {
            return HttpResponse.makeErrRsp("用户不存在");
        }
        if (!user.getLoginPwd().equals(oldPwd)) {
            return HttpResponse.makeErrRsp("原密码错误");
        }
        user.setLoginPwd(newPwd);
        userService.update(user);
        return HttpResponse.makeOKRsp("更新密码成功", null);
    }

    /**
     * 重置密码
     *
     * @param newPwd  新密码
     * @param account 发送验证码的号 手机号或者邮箱号
     * @param code    验证码
     * @return
     */
    @PostMapping("/resetLoginPwd")
    public HttpResult resetLoginPwd(HttpServletRequest request, String newPwd, String account, String code) {
        Integer id = (Integer) request.getAttribute("id");
        User user = userService.selectById(id + "");
        if (user == null) {
            return HttpResponse.makeErrRsp("用户不存在");
        }
        String saveCode = (String) redisUtil.get(account);
        if (saveCode == null) {
            return HttpResponse.makeErrRsp("验证码已过期");
        }
        if (!saveCode.equals(code)) {
            return HttpResponse.makeErrRsp("验证码错误");
        }
        user.setLoginPwd(newPwd);
        userService.update(user);
        redisUtil.del(account);
        return HttpResponse.makeOKRsp("更新密码成功", null);
    }

    /**
     * 更新手机号码
     *
     * @param mobile 手机号码
     * @param code   验证码
     * @return
     */
    @PostMapping("/updateMobile")
    public HttpResult updateMobile(HttpServletRequest request, String mobile, String code) {
        Integer id = (Integer) request.getAttribute("id");
        User user = userService.selectById(id + "");
        if (user == null) {
            return HttpResponse.makeErrRsp("用户不存在");
        }
        String saveCode = (String) redisUtil.get(mobile);
        if (saveCode == null) {
            return HttpResponse.makeErrRsp("验证码已过期");
        }
        if (!saveCode.equals(code)) {
            return HttpResponse.makeErrRsp("验证码错误");
        }
        user.setMobile(mobile);
        userService.update(user);
        redisUtil.del(mobile);
        return HttpResponse.makeOKRsp("设置手机号成功", null);
    }

    /**
     * 更新邮箱
     *
     * @param email
     * @param code
     * @return
     */
    @PostMapping("/updateEmail")
    public HttpResult updateEmail(HttpServletRequest request, String email, String code) {
        Integer id = (Integer) request.getAttribute("id");
        User user = userService.selectById(id + "");
        if (user == null) {
            return HttpResponse.makeErrRsp("用户不存在");
        }
        String saveCode = (String) redisUtil.get(email);
        if (saveCode == null) {
            return HttpResponse.makeErrRsp("验证码已过期");
        }
        if (!saveCode.equals(code)) {
            return HttpResponse.makeErrRsp("验证码错误");
        }
        user.setEmail(email);
        userService.update(user);
        redisUtil.del(email);
        return HttpResponse.makeOKRsp("设置邮箱成功", null);
    }

    /**
     * 设置支付密码
     *
     * @param account 发送验证码的号 手机号或者邮箱号
     * @param payPws  支付密码
     * @param code    验证码
     * @return
     */
    @PostMapping("/updatePayPws")
    public HttpResult updatePayPws(HttpServletRequest request, String account, String payPws, String code) {
        Integer id = (Integer) request.getAttribute("id");
        User user = userService.selectById(id + "");
        if (user == null) {
            return HttpResponse.makeErrRsp("用户不存在");
        }
        String saveCode = (String) redisUtil.get(account);
        if (saveCode == null) {
            return HttpResponse.makeErrRsp("验证码已过期");
        }
        if (!saveCode.equals(code)) {
            return HttpResponse.makeErrRsp("验证码错误");
        }
        user.setPayPwd(payPws);
        userService.update(user);
        redisUtil.del(account);
        return HttpResponse.makeOKRsp("设置支付密码成功", null);
    }

    @PostMapping("/auth")
    public HttpResult auth(String name, String idcard,

                           HttpServletRequest request) throws Exception {
        Integer id = (Integer) request.getAttribute("id");
        User user = userService.selectById(id + "");
        if (user == null) {
            return HttpResponse.makeErrRsp("用户不存在");
        }
        UserAuthInfo userAuthInfoQuery;
        UserAuthInfo userAuthInfo;

        //判断身份证是否已使用
        userAuthInfoQuery = new UserAuthInfo();
        userAuthInfoQuery.setIdcard(idcard);
        userAuthInfo = userAuthInfoService.selectOne(userAuthInfoQuery);
        if (userAuthInfo != null) {
            return HttpResponse.makeErrRsp("该身份证号已被认证");

        }

        //判断该用户是否已实名认证过
        userAuthInfoQuery = new UserAuthInfo();
        userAuthInfoQuery.setUserId(id);
        userAuthInfo = userAuthInfoService.selectOne(userAuthInfoQuery);
        if (userAuthInfo != null) {
            return HttpResponse.makeErrRsp("你已初级实名认证过，无需认证");
        }
        //首次实名认证
        UserAuthInfo userAuthInfoSave = new UserAuthInfo();
        userAuthInfoSave.setUserId(id);
        userAuthInfoSave.setStatus(1);
        userAuthInfoSave.setIdcard(idcard);
        userAuthInfoSave.setName(name);
        userAuthInfoSave.setCreateTime(new Date());
        userAuthInfoService.insert(userAuthInfoSave);
        return HttpResponse.makeOKRsp("初级实名认证成功", null);

    }

    @PostMapping("/auth/high")
    public HttpResult authHigh(String holdImg, String backImg, String frontImg, HttpServletRequest request) throws Exception {
        Integer id = (Integer) request.getAttribute("id");
        User user = userService.selectById(id + "");
        if (user == null) {
            return HttpResponse.makeErrRsp("用户不存在");
        }
        UserAuthInfo userAuthInfoQuery;
        UserAuthInfo userAuthInfoSave;

        //判断该用户是否已实名认证过
        userAuthInfoQuery = new UserAuthInfo();
        userAuthInfoQuery.setUserId(id);
        userAuthInfoSave = userAuthInfoService.selectOne(userAuthInfoQuery);
        if (userAuthInfoSave == null) {
            return HttpResponse.makeErrRsp("请先进行初级实名认证");
        }
        if (userAuthInfoSave.getStatus() == 3) {
            return HttpResponse.makeErrRsp("你已高级实名认证，无需重复认证");
        }
        if (userAuthInfoSave.getStatus() == 2) {
            return HttpResponse.makeErrRsp("高级实名认证审核中，请勿重复提交");
        } else {//未认证过，或已拒绝，
            userAuthInfoSave.setStatus(2);
            userAuthInfoSave.setBackCardPath(backImg);
            userAuthInfoSave.setFrontCardPath(frontImg);
            userAuthInfoSave.setHoldCardPath(holdImg);
            userAuthInfoService.update(userAuthInfoSave);
            return HttpResponse.makeOKRsp("高级实名认证审核中");
        }
    }

    /**
     * 添加支付方式
     *
     * @param payType    支付方式 wx alipay bank
     * @param number     支付账号 微信号或支付宝号，银行卡号
     * @param bank       银行
     * @param bankBranch 支行
     * @param img        图片
     * @return
     * @throws Exception
     */
    @PostMapping("/addPayType")
    public HttpResult addPayType(@RequestParam(name = "payType") String payType,
                                 @RequestParam(name = "number") String number,
                                 @RequestParam(name = "payPwd") String payPwd,
                                 @RequestParam(name = "bank", required = false) String bank,
                                 @RequestParam(name = "bankBranch", required = false) String bankBranch,
                                 @RequestParam(name = "img", required = false) String img,
                                 HttpServletRequest request) throws Exception {
        Integer id = (Integer) request.getAttribute("id");
        User user = userService.selectById(id + "");
        if (user == null) {
            return HttpResponse.makeErrRsp("用户不存在");
        }
        if (user.getPayPwd() == null) {
            return HttpResponse.makeErrRsp("请先设置支付密码");
        }
        if (!user.getPayPwd().equals(payPwd)) {
            return HttpResponse.makeErrRsp("支付密码错误");
        }
        UserPayInfo userPayInfoQuery = new UserPayInfo();
        userPayInfoQuery.setPayType(payType);
        userPayInfoQuery.setUserId(id);
        UserPayInfo userPayInfo = userPayInfoService.selectOne(userPayInfoQuery);
        if (userPayInfo != null) {
            return HttpResponse.makeErrRsp("请勿重复添加支付方式");
        }
        UserPayInfo userPayInfoSave;
        switch (payType) {
            case "wx":
            case "alipay":
                if (img == null) {
                    return HttpResponse.makeErrRsp("参数img找不到");
                }
                userPayInfoSave = new UserPayInfo();
                userPayInfoSave.setUserId(user.getId());
                userPayInfoSave.setNumber(number);
                userPayInfoSave.setPayType(payType);
                userPayInfoSave.setImg(img);
                userPayInfoService.insert(userPayInfoSave);
                return HttpResponse.makeOKRsp("添加成功", null);
            case "bank":
                if (bank == null) {
                    return HttpResponse.makeErrRsp("参数bank找不到");
                }
                if (bankBranch == null) {
                    return HttpResponse.makeErrRsp("参数bankBranch找不到");
                }
                userPayInfoSave = new UserPayInfo();
                userPayInfoSave.setUserId(user.getId());
                userPayInfoSave.setPayType(payType);
                userPayInfoSave.setNumber(number);
                userPayInfoSave.setBank(bank);
                userPayInfoSave.setBankBranch(bankBranch);

                userPayInfoService.insert(userPayInfoSave);
                return HttpResponse.makeOKRsp("添加成功", null);
            default:
                return HttpResponse.makeErrRsp("该支付方式不存在" + payType);
        }

    }

    /**
     * 修改支付方式
     *
     * @param id         支付方式的id
     * @param payType    支付类型
     * @param payPwd
     * @param number     支付账号 微信号或支付宝号，银行卡号
     * @param bank       银行
     * @param bankBranch 支行
     * @param img        图片
     * @return
     * @throws Exception
     */
    @PostMapping("/editPayType")
    public HttpResult editPayType(@RequestParam(name = "id") String id,
                                  @RequestParam(name = "payType") String payType,
                                  @RequestParam(name = "number") String number,
                                  @RequestParam(name = "payPwd") String payPwd,
                                  @RequestParam(name = "bank", required = false) String bank,
                                  @RequestParam(name = "bankBranch", required = false) String bankBranch,
                                  @RequestParam(name = "img", required = false) String img,
                                  HttpServletRequest request) throws Exception {
        User user = userService.selectById((Integer) request.getAttribute("id") + "");
        if (user == null) {
            return HttpResponse.makeErrRsp("用户不存在");
        }
        if (!user.getPayPwd().equals(payPwd)) {
            return HttpResponse.makeErrRsp("支付密码错误");
        }
        UserPayInfo userPayInfo = userPayInfoService.selectById(id);
        if (userPayInfo == null) {
            return HttpResponse.makeErrRsp("该支付方式不存在,请先添加");
        }
        switch (payType) {
            case "wx":
            case "alipay":
                if (img == null) {
                    return HttpResponse.makeErrRsp("参数img找不到");
                }
                userPayInfo.setNumber(number);
                userPayInfo.setImg(img);
                userPayInfoService.update(userPayInfo);
                return HttpResponse.makeOKRsp("修改成功", null);
            case "bank":
                if (bank == null) {
                    return HttpResponse.makeErrRsp("参数bank找不到");
                }
                if (bankBranch == null) {
                    return HttpResponse.makeErrRsp("参数bankBranch找不到");
                }
                userPayInfo.setNumber(number);
                userPayInfo.setBank(bank);
                userPayInfo.setBankBranch(bankBranch);
                userPayInfoService.update(userPayInfo);
                return HttpResponse.makeOKRsp("修改成功", null);
            default:
                return HttpResponse.makeErrRsp("该支付方式不存在" + payType);
        }
    }

    /**
     * 更改支付方式状态
     *
     * @param id     支付方式的id
     * @param isOpen 开启 true,关闭 false
     * @return
     */
    @PostMapping("/togglePayType")
    public HttpResult togglePayType(String id, boolean isOpen, HttpServletRequest request) {
        User user = userService.selectById((Integer) request.getAttribute("id") + "");
        if (user == null) {
            return HttpResponse.makeErrRsp("用户不存在");
        }
        UserPayInfo userPayInfo = userPayInfoService.selectById(id);
        if (userPayInfo == null) {
            return HttpResponse.makeErrRsp("该支付方式不存在,请先添加");
        }
        userPayInfo.setIsOpen(isOpen);
        userPayInfoService.update(userPayInfo);
        return HttpResponse.makeOKRsp(isOpen ? "开启成功" : "关闭成功", null);

    }

    /**
     * 添加钱包地址
     *
     * @param userWalletAddress
     * @return
     */
    @PostMapping("/addWalletAddress")
    public HttpResult addWalletAddress(UserWalletAddress userWalletAddress, HttpServletRequest request) {
        User user = userService.selectById((Integer) request.getAttribute("id") + "");
        if (user == null) {
            return HttpResponse.makeErrRsp("用户不存在");
        }
        // TODO: 18-11-8  检测钱包地址是否合法
        userWalletAddress.setUserId(user.getId());
        userWalletAddress.setCreateTime(new Date());
        userWalletAddressService.insert(userWalletAddress);
        return HttpResponse.makeOKRsp("添加成功", null);
    }

    @PostMapping("/delWalletAddress")
    public HttpResult delWalletAddress(String id, HttpServletRequest request) {
        User user = userService.selectById((Integer) request.getAttribute("id") + "");
        if (user == null) {
            return HttpResponse.makeErrRsp("用户不存在");
        }

        userWalletAddressService.deleteById(id);
        return HttpResponse.makeOKRsp("删除成功", null);
    }

    /**
     * 获取钱包地址列表
     *
     * @return
     */
    @PostMapping("/getWalletAddressList")
    public HttpResult getWalletAddressList(HttpServletRequest request) {
        User user = userService.selectById((Integer) request.getAttribute("id") + "");
        if (user == null) {
            return HttpResponse.makeErrRsp("用户不存在");
        }

        Example example = Example.builder(UserWalletAddress.class)
                .orderBy("type")
                .build();
        example.createCriteria()
                .andEqualTo("userId", user.getId());

        List<UserWalletAddress> userWalletAddresses = userWalletAddressService.selectByCondition(example);
        HashMap<String, List<UserWalletAddress>> map = new HashMap<>();
        ArrayList<UserWalletAddress> list = null;
        for (UserWalletAddress userWalletAddress : userWalletAddresses) {
            if (map.get(userWalletAddress.getType()) == null) {
                list = new ArrayList<>();
                map.put(userWalletAddress.getType().toUpperCase(), list);
            }
            list.add(userWalletAddress);
        }
        return HttpResponse.makeOKRsp("查询成功", map);
    }

    /**
     * 获取用户资产列表
     *
     * @return
     */
    @PostMapping("/getUserAssets")
    public HttpResult getUserAssets(HttpServletRequest request) {
        User user = userService.selectById((Integer) request.getAttribute("id") + "");
        if (user == null) {
            return HttpResponse.makeErrRsp("用户不存在");
        }
        List<SystemAsset> systemAssets = systemAssetService.selectAll();
        List<UserAsset> userAssets = userAssetService.selectListBy("userId", user.getId());

        ArrayList<UserAsset> userAssetsReturn = new ArrayList<>();
        systemAssets.forEach(systemAsset -> {
            int j = -1;
            for (int i = 0; i < userAssets.size(); i++) {
                if (userAssets.get(i).getType().equals(systemAsset.getType())) {
                    j = i;
                    break;
                }
            }
            if (j != -1) {
                userAssetsReturn.add(userAssets.get(j));
            } else {
                UserAsset e = new UserAsset();
                e.setType(systemAsset.getType());
                e.setAvailable("0");
                e.setFreeze("0");
                userAssetsReturn.add(e);
            }
        });
        return HttpResponse.makeOKRsp(userAssetsReturn);
    }

    /**
     * 获取充值提现记录
     *
     * @param assetType 资产类型
     * @param type      0 充值 1 提现
     * @return
     */
    @PostMapping("/getAssetRecords")
    public HttpResult getAssetRecords(String assetType, int type, HttpServletRequest request) {
        User user = userService.selectById((Integer) request.getAttribute("id") + "");
        if (user == null) {
            return HttpResponse.makeErrRsp("用户不存在");
        }
        Example example = Example.builder(UserAssetRecord.class)
                .build();
        example
                .createCriteria()
                .andEqualTo("userId", user.getId())
                .andEqualTo("type", type)
                .andEqualTo("assetType", assetType);
        List<UserAssetRecord> userAssets = userAssetRecordService.selectByCondition(example);
        return HttpResponse.makeOKRsp("获取成功", userAssets);
    }

    /**
     * 根据id删除用户
     *
     * @param id 用户id
     * @return
     * @throws Exception
     */
    @PostMapping("/deleteById")
    public HttpResult<Integer> deleteById(@RequestParam String id) throws Exception {
        Integer state = userService.deleteById(id);
        return HttpResponse.makeOKRsp(state);
    }

    /**
     * 更新数据
     *
     * @param user 用户信息
     * @return
     * @throws Exception
     */
    @PostMapping("/update")
    public HttpResult<Integer> update(User user) throws Exception {
        Integer state = userService.update(user);
        return HttpResponse.makeOKRsp(state);
    }

    /**
     * 根据id 选择用户
     *
     * @param id 用户id
     * @return
     * @throws Exception
     */
    @PostMapping("/selectById")
    public HttpResult<User> selectById(@RequestParam String id) throws Exception {
        User user = userService.selectById(id);
        return HttpResponse.makeOKRsp(user);
    }

    /**
     * 分页查询
     *
     * @param page 页码
     * @param size 每页条数
     * @Description: 分页查询
     * @Reutrn RetResult<PageInfoUser>>
     */
    @PostMapping("/list")
    public HttpResult<PageInfo<User>> list(@RequestParam(defaultValue = "0") Integer page,
                                           @RequestParam(defaultValue = "0") Integer size) throws Exception {
        PageHelper.startPage(page, size);
        List<User> list = userService.selectAll();
        PageInfo<User> pageInfo = new PageInfo<User>(list);
        return HttpResponse.makeOKRsp(pageInfo);
    }
}

